﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Pahan.McuFusion.Common;

namespace Pahan.McuFusion.FusionBoot
{
    [Serializable]
    internal class FusionBootAdapter : IFusionBootAdapter
    {
        public FusionBootAdapter(IFusionBootInterface @interface, FusionBootAdapterInfo info)
        {
            Assert.NotNull(@interface, "interface");
            this.fusionInterface = @interface;
            this.Info = info;
        }
        
        #region Implementation of IDisposable

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        /// <filterpriority>2</filterpriority>
        public void Dispose()
        {
            fusionInterface.Dispose();
        }

        #endregion

        #region Implementation of IHardwareAdapter

        /// <summary>
        /// Gets the information about the adapter.
        /// </summary>
        public HardwareAdapterInfo Info
        {
            get;
            private set;
        }

        /// <summary>
        /// Opens the adapter. This method must be called before the actual use of the adapter.
        /// </summary>
        public void Open()
        {
            fusionInterface.Open();
        }

        /// <summary>
        /// Closes the adapter.
        /// </summary>
        public void Close()
        {
            fusionInterface.Close();
        }

        #endregion

        #region Implementation of IFusionBootAdapter

        public void WriteByte(byte value)
        {
            fusionInterface.WriteByte(value);
        }

        public void Write(IList<byte> data)
        {
            fusionInterface.Write(data);
        }

        public void WriteWithControlSum(IList<byte> data)
        {
            WriteWithControlSum(data, 0);
        }

        public void WriteWithControlSum(IList<byte> data, byte controlSumInitial)
        {
            List<byte> dataWithControlSum = new List<byte>(data);
            byte controlSum = data.ControlSum(controlSumInitial);
            dataWithControlSum.Add(controlSum);
            fusionInterface.Write(dataWithControlSum);
        }

        public byte ReadByte()
        {
            return fusionInterface.ReadByte();
        }

        public void Read(IList<byte> data)
        {
            for (int i = 0; i < data.Count; i++)
            {
                data[i] = fusionInterface.ReadByte();
            }
        }

        public bool ReadWithControlSum(IList<byte> data)
        {
            return ReadWithControlSum(data, 0);
        }

        public bool ReadWithControlSum(IList<byte> data, byte controlSumInitial)
        {
            Read(data);
            var sum = ReadByte();
            return sum == data.ControlSum(controlSumInitial);
        }

        public void DiscardInputBuffer()
        {
            fusionInterface.DiscardInputBuffer();
        }

        public void DiscardOutputBuffer()
        {
            fusionInterface.DiscardOutputBuffer();
        }

        #endregion

        #region Private Members

        private readonly IFusionBootInterface fusionInterface;

        #endregion

    }
}
